"""
可解释的提示词工程模块
提供决策解释、评估依据和优化建议说明
"""

from typing import Dict, List, Any, Optional
from src.research_core.prompt_eng_state import PromptEngineeringState


class ExplainablePromptEngineering:
    """
    可解释的提示词工程类
    提供对决策过程、评估结果和优化建议的详细解释
    """
    
    def __init__(self):
        self.explanation_history: List[Dict[str, Any]] = []
    
    def explain_decision(self, state: PromptEngineeringState, decision: str) -> Dict[str, Any]:
        """
        解释决策的依据
        
        Args:
            state: 当前状态
            decision: 做出的决策
            
        Returns:
            包含决策解释的字典
        """
        explanation = {
            "decision": decision,
            "timestamp": self._get_current_timestamp(),
            "reasoning": "",
            "factors": {},
            "confidence": 0.0
        }
        
        if decision == "optimize":
            explanation["reasoning"] = "系统决定继续优化提示词"
            explanation["factors"] = self._analyze_optimization_factors(state)
            explanation["confidence"] = self._calculate_decision_confidence(
                explanation["factors"]
            )
        elif decision == "finalize":
            explanation["reasoning"] = "系统决定完成提示词工程流程"
            explanation["factors"] = self._analyze_finalization_factors(state)
            explanation["confidence"] = self._calculate_decision_confidence(
                explanation["factors"]
            )
        elif decision == "process_feedback":
            explanation["reasoning"] = "系统检测到人工反馈，需要处理反馈"
            explanation["factors"] = self._analyze_feedback_factors(state)
            explanation["confidence"] = 1.0  # 反馈存在时置信度为100%
        elif decision == "evaluate":
            explanation["reasoning"] = "系统未检测到反馈，直接进入评估阶段"
            explanation["factors"] = {"human_feedback_present": False}
            explanation["confidence"] = 1.0
        
        # 记录解释历史
        self.explanation_history.append(explanation)
        
        return explanation
    
    def _analyze_optimization_factors(self, state: PromptEngineeringState) -> Dict[str, Any]:
        """分析优化决策的相关因素"""
        factors = {
            "human_intervened": state.get('human_intervened', False),
            "quality_score": state.get('quality_score', 0.0),
            "iteration_count": state.get('iteration_count', 0),
            "quality_threshold": 0.8,
            "max_iterations": 5
        }
        
        # 添加详细分析
        factors["quality_below_threshold"] = factors["quality_score"] < factors["quality_threshold"]
        factors["iteration_within_limit"] = factors["iteration_count"] < factors["max_iterations"]
        
        return factors
    
    def _analyze_finalization_factors(self, state: PromptEngineeringState) -> Dict[str, Any]:
        """分析完成决策的相关因素"""
        factors = {
            "human_intervened": state.get('human_intervened', False),
            "quality_score": state.get('quality_score', 0.0),
            "iteration_count": state.get('iteration_count', 0),
            "quality_threshold": 0.8,
            "max_iterations": 5
        }
        
        # 添加详细分析
        factors["quality_meets_threshold"] = factors["quality_score"] >= factors["quality_threshold"]
        factors["iteration_limit_reached"] = factors["iteration_count"] >= factors["max_iterations"]
        
        return factors
    
    def _analyze_feedback_factors(self, state: PromptEngineeringState) -> Dict[str, Any]:
        """分析反馈处理决策的相关因素"""
        human_feedback = state.get('human_feedback', '')
        return {
            "human_feedback_present": bool(human_feedback),
            "feedback_length": len(human_feedback) if human_feedback else 0,
            "feedback_type": self._classify_feedback_type(human_feedback or '')
        }
    
    def _classify_feedback_type(self, feedback: str) -> str:
        """分类反馈类型"""
        if not feedback:
            return "none"
        
        feedback_lower = feedback.lower()
        if any(keyword in feedback_lower for keyword in ["结构", "structure"]):
            return "structure"
        elif any(keyword in feedback_lower for keyword in ["内容", "content"]):
            return "content"
        elif any(keyword in feedback_lower for keyword in ["格式", "format"]):
            return "format"
        elif any(keyword in feedback_lower for keyword in ["清晰", "clear"]):
            return "clarity"
        else:
            return "general"
    
    def _calculate_decision_confidence(self, factors: Dict[str, Any]) -> float:
        """计算决策置信度"""
        # 基于因素数量和明确性计算置信度
        if not factors:
            return 0.0
        
        # 简单的置信度计算方法
        explicit_factors = sum(1 for v in factors.values() if isinstance(v, (bool, int, float)))
        total_factors = len(factors)
        
        return min(1.0, explicit_factors / max(1, total_factors))
    
    def explain_quality_score(self, state: PromptEngineeringState) -> Dict[str, Any]:
        """
        解释质量评分的依据
        
        Args:
            state: 当前状态
            
        Returns:
            包含评分解释的字典
        """
        quality_evaluation = state.get('quality_evaluation_details', {})
        if not quality_evaluation:
            return {
                "explanation": "无质量评估详情可用",
                "score_breakdown": {},
                "recommendations": []
            }
        
        explanation = {
            "overall_score": quality_evaluation.get("overall_score", 0.0),
            "explanation": "提示词质量评分基于多个维度的综合评估",
            "score_breakdown": self._breakdown_quality_scores(quality_evaluation),
            "weighting": {
                "clarity": "20%",
                "completeness": "25%",
                "specificity": "20%",
                "relevance": "20%",
                "structuredness": "15%"
            },
            "recommendations": self._generate_quality_recommendations(quality_evaluation)
        }
        
        return explanation
    
    def _breakdown_quality_scores(self, quality_evaluation: Dict[str, Any]) -> Dict[str, Any]:
        """分解质量评分"""
        breakdown = {}
        for key, value in quality_evaluation.items():
            if key != "details":
                breakdown[key] = {
                    "score": value,
                    "description": self._get_dimension_description(key)
                }
        return breakdown
    
    def _get_dimension_description(self, dimension: str) -> str:
        """获取评估维度的描述"""
        descriptions = {
            "clarity": "评估提示词语言的明确性和无歧义性",
            "completeness": "检查提示词是否包含关键组成部分",
            "specificity": "评估提示词的具体明确程度",
            "relevance": "评估提示词与原始需求的相关性",
            "structuredness": "评估提示词的结构化程度",
            "ml_score": "基于机器学习模型的语义质量评估"
        }
        return descriptions.get(dimension, "未知维度")
    
    def _generate_quality_recommendations(self, quality_evaluation: Dict[str, Any]) -> List[str]:
        """生成质量改进建议"""
        recommendations = []
        threshold = 0.7  # 评分阈值，低于此值需要改进建议
        
        for dimension, score in quality_evaluation.items():
            if isinstance(score, (int, float)) and score < threshold:
                if dimension == "clarity":
                    recommendations.append("提高提示词清晰度：使用更明确的表述，避免模糊词汇")
                elif dimension == "completeness":
                    recommendations.append("完善提示词结构：确保包含目标、要求、输出格式等关键元素")
                elif dimension == "specificity":
                    recommendations.append("增加提示词具体性：添加具体示例、约束条件或量化指标")
                elif dimension == "relevance":
                    recommendations.append("增强与需求的相关性：重新审视原始需求，确保提示词紧扣主题")
                elif dimension == "structuredness":
                    recommendations.append("改善提示词结构：使用编号列表、标题等方式组织内容")
                elif dimension == "ml_score":
                    recommendations.append("参考高质量示例：学习系统内置的高质量提示词模板")
        
        if not recommendations:
            recommendations.append("提示词质量良好，无需重大改进")
        
        return recommendations
    
    def explain_optimization_suggestion(self, state: PromptEngineeringState) -> Dict[str, Any]:
        """
        解释优化建议的生成逻辑
        
        Args:
            state: 当前状态
            
        Returns:
            包含优化建议解释的字典
        """
        # 获取评估详情和反馈历史
        quality_evaluation = state.get('quality_evaluation_details', {}) or {}
        feedback_history = state.get('feedback_history', [])
        prompt_evaluation = state.get('prompt_evaluation', '') or ''
        
        explanation = {
            "logic": "优化建议基于以下信息生成：",
            "sources": {
                "quality_evaluation": bool(quality_evaluation),
                "feedback_history": len(feedback_history),
                "prompt_evaluation": bool(prompt_evaluation)
            },
            "process": [
                "1. 分析质量评估结果，识别低分维度",
                "2. 检查历史反馈，了解人工关注点",
                "3. 结合自动评估和人工反馈生成针对性建议",
                "4. 提供具体的改进措施"
            ],
            "suggestions": self._generate_optimization_suggestions(
                quality_evaluation, feedback_history, prompt_evaluation
            )
        }
        
        return explanation
    
    def _generate_optimization_suggestions(self, 
                                         quality_evaluation: Dict[str, Any],
                                         feedback_history: List[Dict[str, Any]],
                                         prompt_evaluation: str) -> List[str]:
        """生成优化建议"""
        suggestions = []
        
        # 基于质量评估生成建议
        quality_suggestions = self._generate_quality_recommendations(quality_evaluation)
        suggestions.extend(quality_suggestions)
        
        # 基于反馈历史生成建议
        if feedback_history:
            latest_feedback = feedback_history[-1]  # 获取最新反馈
            feedback_content = latest_feedback.get('content', '')
            if feedback_content:
                suggestions.append(f"根据最新反馈进行调整: {feedback_content[:100]}...")
        
        # 基于提示词评估生成建议
        if prompt_evaluation and "失败" not in prompt_evaluation:
            # 简单的关键词提取
            key_points = []
            for keyword in ["结构", "内容", "格式", "清晰度"]:
                if keyword in prompt_evaluation:
                    key_points.append(keyword)
            
            if key_points:
                suggestions.append(f"关注以下方面: {', '.join(key_points)}")
        
        return suggestions
    
    def get_explanation_history(self) -> List[Dict[str, Any]]:
        """获取解释历史"""
        return self.explanation_history
    
    def clear_explanation_history(self):
        """清空解释历史"""
        self.explanation_history.clear()
    
    def _get_current_timestamp(self) -> str:
        """获取当前时间戳"""
        import datetime
        return datetime.datetime.now().isoformat()


def create_explainable_prompt_engineering() -> ExplainablePromptEngineering:
    """
    创建可解释的提示词工程实例
    
    Returns:
        配置好的ExplainablePromptEngineering实例
    """
    return ExplainablePromptEngineering()


# 导出类和函数
__all__ = [
    'ExplainablePromptEngineering',
    'create_explainable_prompt_engineering'
]